package com.assistant.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

/**
 * @author Anyang
 * @version 1.0.0
 * @date 2025/10/25 05:10:31
 * @description 配置文件：管理百度千帆及语音服务的核心参数
 */
public class Config {
    private static final String PROJECT_ROOT = System.getProperty("user.dir");

    public static final String KEYWORD_PATH = PROJECT_ROOT + File.separator + "calf_zh_windows_v3_0_0.ppn";
    public static final String PORCUPINE_MODEL_PATH = PROJECT_ROOT + File.separator + "porcupine_params_zh.pv";

    private static final Logger logger = LoggerFactory.getLogger(Config.class);

    // 百度通用 API 密钥 (用于 TTS/STT 换取 Access Token)
    public static final String BAIDU_API_KEY = System.getenv("BAIDU_API_KEY");
    public static final String BAIDU_SECRET_KEY = System.getenv("BAIDU_SECRET_KEY");

    // 【核心】专用于 NLU/LLM（千帆模型）的 API Key。此 Key 将直接用作 Bearer Token。
    public static final String LLM_API_KEY = System.getenv("BAIDU_LLM_API_KEY");
    public static final String PICOVOICE_ACCESS_KEY = System.getenv("PICOVOICE_ACCESS_KEY");

    // 百度千帆模型配置ernie-4.0-8k
    public static final String QIANFAN_MODEL_NAME = "ernie-4.5-turbo-vl";
    // 【BUG修复】这里是核心修正点。更新为正确的千帆 ERNIE-4.0-8K 模型 API 地址。
    public static final String QIANFAN_CHAT_URL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro";

    // 百度语音识别(STT)API地址（短语音识别）
    public static final String BAIDU_STT_URL = "https://vop.baidu.com/server_api";

    // 百度语音合成(TTS)API地址
    public static final String BAIDU_TTS_URL = "https://tsn.baidu.com/text2audio";

    // 【【【 新增：VAD 配置 (从 MainApplication 迁移) 】】】
    // 16位音频 (short) 的范围是 -32768 到 32767。
    // 2000.0 是一个示例值，代表安静环境下的说话音量。
    // 如果太灵敏（噪音触发）：调高此值 (例如 3000.0)
    // 如果太迟钝（听不到话）：调低此值 (例如 1000.0)
    public static final double VAD_ENERGY_THRESHOLD = 2000.0;

    // Porcupine 帧长 = 512 采样点 / 16000 Hz = 0.032s = 32ms
    // 75 帧 * 32ms = 2400ms (2.4s) 静音
    public static final int VAD_SILENCE_FRAMES_REQUIRED = 75; // 75 帧
    // ---------------------------------------------------

    // 系统指令：给 LLM 的角色设定和输出要求
    // 【优化】优化了系统指令，要求模型严格返回 JSON，以匹配 NLUModule 中不使用 Function Calling 的实现方式。
    public static final String SYSTEM_PROMPT = "你是一个桌面上运行的 AI 语音助手，能够将用户的自然语言请求转化为一个结构化的 JSON 命令。" +
            "你必须严格只返回一个 JSON 对象，不要添加任何额外的解释或说明文字（包括 ```json 标记）。\n" +
            "JSON 格式必须严格包含 'action', 'target', 和 'prompt' 三个字段。\n\n" +

            "【核心规则】:\n" +
            // 【修改】1. 从 action 列表中移除 'error'
            "1. 'action' 必须是 'open_app', 'open_url', 'create_text', 'answer_question', 'play_music' 之一。\n" +
            "2. 【操作指令】(open_app, open_url): 'target' 包含目标，'prompt' 必须为空字符串 \"\"。\n" +
            "3. 【内容创作】(create_text): 当用户要求“写”、“创建”、“生成”并希望粘贴到电脑上时使用。'action' 为 'create_text'，'prompt' 包含生成提示词。\n" +
            // 【修改】4. 扩展 answer_question，使其包含“闲聊”
            "4. 【问答/闲聊】(answer_question): 当用户“提问”、“查询”、“翻译”、“解释”或进行“闲聊”时使用。'action' 为 'answer_question'，'prompt' 包含用于回答的原始用户输入。\n" +
            "5. 【播放音乐】(play_music): 当用户要求“播放音乐”、“听歌”、“来点音乐”时使用。'action' 为 'play_music'。如果只是说“打开音乐”，那应该使用 'open_app'。"+
            // 【修改】5. 移除原有的 'error' 规则
            "--- 示例 --- \n\n" +

            "示例 1 (操作 - 打开应用):\n" +
            "用户: \"打开我的QQ\"\n" +
            "{\"action\": \"open_app\", \"target\": \"QQ\", \"prompt\": \"\"}\n\n" +

            "示例 2 (操作 - 打开网址):\n" +
            "用户: \"打开B站\"\n" +
            "{\"action\": \"open_url\", \"target\": \"[https://www.bilibili.com](https://www.bilibili.com)\", \"prompt\": \"\"}\n\n" +

            "示例 3 (内容创作 - 粘贴):\n" +
            "用户: \"帮我写一首关于月亮的诗\"\n" +
            "{\"action\": \"create_text\", \"target\": \"\", \"prompt\": \"写一首关于月亮的诗\"}\n\n" +

            "示例 4 (内容创作 - 粘贴):\n" +
            "用户: \"帮我起草一封邮件给张三，内容是...\"\n" +
            "{\"action\": \"create_text\", \"target\": \"\", \"prompt\": \"起草一封邮件给张三，内容是...\"}\n\n" +

            "示例 5 (知识问答 - 回答):\n" +
            "用户: \"什么什么是HTTP协议\"\n" +
            "{\"action\": \"answer_question\", \"target\": \"\", \"prompt\": \"请详细解释一下什么是HTTP协议\"}\n\n" +

            "示例 6 (知识问答 - 回答):\n" +
            "用户: \"'语音助手'用英文怎么说\"\n" +
            "{\"action\": \"answer_question\", \"target\": \"\", \"prompt\": \"把 '语音助手' 翻译成英文\"}\n\n" +

            "示例 7 (闲聊 - 问答):\n" +
            "用户: \"你好吗\"\n" +
            "{\"action\": \"answer_question\", \"target\": \"\", \"prompt\": \"你好吗\"}\n\n" +

            "示例 8 (闲聊 - 问答):\n" +
            "用户: \"你叫什么名字\"\n" +
            "{\"action\": \"answer_question\", \"target\": \"\", \"prompt\": \"你叫什么名字\"}\n\n" +

            "示例 9 (播放音乐 - 无目标):\n" +
            "用户: \"我想听歌\"\n" +
            "{\"action\": \"play_music\", \"target\": \"\", \"prompt\": \"\"}\n\n" +

            "示例 10 (播放音乐 - 有目标):\n" +
            "用户: \"来一首红尘情歌\"\n" +
            "{\"action\": \"play_music\", \"target\": \"红尘情歌\", \"prompt\": \"\"}"+

            "示例 11 (重要区分 - 打开应用):\n" +
            "用户: \"打开网易云音乐\"\n" +
            "{\"action\": \"open_app\", \"target\": \"网易云音乐\", \"prompt\": \"\"}";


    public static final String CHAT_SYSTEM_PROMPT = "你是一个AI助手，但你的任务是扮演一个真实的人类朋友。" +
            "你的性格友好、随意，甚至可以带点幽默感。" +
            "【核心规则】：" +
            "1. 你的回答必须非常简短、口语化，像朋友聊天一样。不要长篇大论。" +
            "2. 绝对不要使用敬语（比如 '您'），统一使用 '你'。" +
            "3. 不要自称 'AI' 或 '助手'，用 '我' 就行了。";
    // 调试配置
    public static final boolean DEBUG_MODE = true; // 调试模式开关
    public static boolean ENABLE_MOCK = false; // 关闭模拟模式（实际调用API）

    /**
     * 简单的配置有效性检查
     */
    public static boolean isConfigValid() {
        // 只要 LLM Key 存在，就认为 LLM 功能可用
        boolean isLlmKeyValid = LLM_API_KEY != null && !LLM_API_KEY.trim().isEmpty();
        // 语音服务的 Key/Secret 必须配对存在
        boolean isAudioKeyValid = BAIDU_API_KEY != null && !BAIDU_API_KEY.trim().isEmpty() &&
                BAIDU_SECRET_KEY != null && !BAIDU_SECRET_KEY.trim().isEmpty();
        // 【新增】PicoVoice Key 必须存在
        boolean isPicoKeyValid = PICOVOICE_ACCESS_KEY != null && !PICOVOICE_ACCESS_KEY.trim().isEmpty();

        // 【修改】调整逻辑：唤醒词必须有效，其他两者至少有一个有效
        return isPicoKeyValid && (isLlmKeyValid || isAudioKeyValid);
    }

    /**
     * 验证配置有效性并输出日志
     */
    public static void checkConfig() {
        logger.info("--- 开始验证配置有效性 ---");

        // 【新增】验证 PICOVOICE_ACCESS_KEY
        if (PICOVOICE_ACCESS_KEY != null && !PICOVOICE_ACCESS_KEY.trim().isEmpty()) {
            logger.info("【配置验证】**Picovoice Access Key** 已加载，用于唤醒词服务。");
        } else {
            logger.error("【配置错误】致命错误：PICOVOICE_ACCESS_KEY 缺失，唤醒词无法启动。");
        }

        // 通用百度 Key (用于 TTS/STT)
        if (BAIDU_API_KEY != null && !BAIDU_API_KEY.trim().isEmpty() &&
                BAIDU_SECRET_KEY != null && !BAIDU_SECRET_KEY.trim().isEmpty()) {
            logger.info("【配置验证】**百度 Key/Secret** 已加载，用于获取 Access Token。");
        } else {
            logger.warn("【配置警告】通用百度 Key/Secret 缺失，TTS/STT 模块可能无法正常工作。");
        }

        // LLM 专用 Key (用于 NLU)
        if (LLM_API_KEY != null && !LLM_API_KEY.trim().isEmpty()) {
            logger.info("【配置验证】**LLM 专用 API Key** 已加载，用于直接调用千帆模型。");
        } else {
            logger.warn("【配置警告】LLM 专用 API Key 缺失，NLU 功能将依赖通用 Key。");
        }

        if (!isConfigValid()) {
            // 【修改】提供更明确的错误
            logger.error("【配置验证】致命错误：配置不完整。请确保 PICOVOICE_ACCESS_KEY 以及 (百度 Key 或 LLM Key) 均已设置。");
            // 可以在此处抛出异常或退出，以防止后续错误
            // System.exit(1);
        }

        logger.info("--- 配置验证完成 ---");
    }
}